package org.example.dataHandle;

import java.util.ArrayDeque;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Optional;

public class Data<T extends Number> {

    protected ArrayDeque<Pair<T, Long>> data;

    public Data(){
        data = new ArrayDeque<>();
    }

    public void add(Pair<T,Long> source){
        data.add(source);
    }

    public void clear(){
        synchronized (this){
            data = new ArrayDeque<>();
        }
    }

    public static class Pair<T extends Number,V extends Number>{
        protected T first;
        protected V second;
        public Pair(T first,V second){
            this.first = first;
            this.second = second;
        }

        public T getFirst(){
            return first;
        }
        public V getSecond(){
            return second;
        }

        public void setFirst(T first) {
            this.first = first;
        }

        public void setSecond(V second) {
            this.second = second;
        }
    }
    //给整个容器上锁以免data被中途释放掉导致空指针
    public Pair<T, Long> getLatest(){
        synchronized (this){
            if(data.isEmpty())
                return null;
            Pair<T,Long> temp;
            temp = data.getLast();
            return temp;
        }
    }

    public Pair<T,Long> getFront(){
        synchronized (this){
            if(data.isEmpty())
                return null;
            Pair<T,Long> temp;
            temp = data.getFirst();
            return temp;
        }
    }

    public T getMinValue(){
        Optional<Pair<T,Long>> value = data.stream().min(Comparator.comparing(p -> p.getFirst().doubleValue()));
        return value.map(tLongPair -> tLongPair.first).orElse(null);
    }

    public T getMaxValue(){
        Optional<Pair<T,Long>> value = data.stream().max(Comparator.comparing(p -> p.getFirst().doubleValue()));
        return value.map(tLongPair -> tLongPair.first).orElse(null);
    }

    public double getAverageValue(){
        return data.stream().mapToDouble(t->t.first.doubleValue()).average().orElse(0);
    }

    public boolean isEmpty(){return data.isEmpty();}
    public Iterator<Pair<T,Long>> getIterator(){return data.iterator();}
}
